package com.lau.service.impl;

import com.lau.common.exception.CaptchaException;
import com.lau.common.exception.DebugException;
import com.lau.common.lang.Result;
import com.lau.constant.CacheConstants;
import com.lau.security.LoginUser;
import com.lau.utils.JwtUtils;
import com.lau.utils.RedisUtil;
import com.lau.vo.LoginBodyVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author:Lau
 * @create: 2023-11-22 17:08
 * @Description: 登录处理
 */
@Service
public class SysLoginService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    JwtUtils jwtUtils;

    public Result login(LoginBodyVo loginBodyVo) {
        // 验证码校验
        validateCaptcha(loginBodyVo);
        String username = loginBodyVo.getUsername();
        String password = loginBodyVo.getPassword();
        //前置校验
        loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            // 该方法会去调用UserDetailServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new DebugException("用户名或密码错误");
            } else {
                throw new DebugException("其他问题");
            }
        }
        //生成token
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String jwt = jwtUtils.createToken(loginUser);
        return Result.succ(jwt);
    }

    /**
     * 验证码校验
     *
     * @param loginBodyVo
     */
    private void validateCaptcha(LoginBodyVo loginBodyVo) {
        if (StringUtils.isAnyBlank(loginBodyVo.getVerCode(), loginBodyVo.getUuid())) {
            throw new CaptchaException("验证码错误");
        }
        // 判断验证码
        if (!loginBodyVo.getVerCode().equals(redisUtil.hget(CacheConstants.CAPTCHA_CODE_KEY, loginBodyVo.getUuid()))) {
            throw new CaptchaException("验证码错误");
        }

        // 一次性使用
        redisUtil.hdel(CacheConstants.CAPTCHA_CODE_KEY, loginBodyVo.getUuid());
    }

    /**
     * 登录前置校验
     *
     * @param username 用户名
     * @param password 用户密码
     *                 TODO
     */
    public void loginPreCheck(String username, String password) {
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)) {
            throw new DebugException("用户名或密码错误");
        }
        //用户名长度校验
        // IP黑名单校验

    }
}
